﻿using Sustainalytics.Entities;
using Sustainalytics.SharedEntities.EsgResearch;
using Sustainalytics.Synchronization.Interface;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;

namespace Sustainalytics.ClientDW.Synchronization.SyncESGData.EsgResearchProfileLogic
{
    public class EsgResearchProfileQuery : ICoreEsgResearchProfileQuery, IComprehensiveEsgResearchProfileQuery
    {
        private readonly ILogger logger;
        private readonly BackOfficeAppSettings backOfficeAppSettings;
        private readonly ResearchDataProvider.ResearchDataProvider researchDataProvider;

        public EsgResearchProfileQuery(ResearchDataProvider.ResearchDataProvider researchDataProvider, BackOfficeAppSettings backOfficeAppSettings, ILogger logger)
        {
            this.researchDataProvider = researchDataProvider;
            this.logger = logger;
            this.backOfficeAppSettings = backOfficeAppSettings;

            logger.Log($"\nWorking with HBase Thrift server {backOfficeAppSettings.ThriftServer} and Phoenix server {backOfficeAppSettings.PhoenixServer}");
        }

        IList<EsgResearchProfile> ICoreEsgResearchProfileQuery.Get(IList<Guid> companiesIds)
        {
            return GetData(ResearchDataProvider.Models.Analyst_Interface.FrameworkCodes.FocusedRatings, companiesIds);
        }

        IList<EsgResearchProfile> IComprehensiveEsgResearchProfileQuery.Get(IList<Guid> companiesIds)
        {
            return GetData(ResearchDataProvider.Models.Analyst_Interface.FrameworkCodes.ComprehensiveRatings, companiesIds);
        }

        private IList<EsgResearchProfile> GetData(string frameworkId, IList<Guid> companiesIds)
        {
            var callerMethod = new StackFrame(1).GetMethod().Name;

            var stopWatch = Stopwatch.StartNew();

            logger.Log($"Start getting data from the cluster for {callerMethod}: requested {companiesIds.Count} companies");

            if (companiesIds.Count == 0) return null;
            
            var esgResearchProfiles = Retry.Do(() => researchDataProvider.GetEsgResearchProfile(frameworkId, companiesIds.ToList()).ToList(),
                                                 backOfficeAppSettings.WaitRetryDuration, 
                                                 logger, 
                                                 backOfficeAppSettings.RetryNumberOfTimes);
            var rpIndicatorPerformanceIndicators = esgResearchProfiles.Select(rp => rp.ComputationResult).SelectMany(rp => rp.Indicators).Count();
            var rpIndicatorExtendedIndicators = esgResearchProfiles.SelectMany(rp => rp.Indicators).Count();

            logger.Log($"Finished getting data from the cluster for {callerMethod}: requested {companiesIds.Count()} companies, received {esgResearchProfiles.Count} companies" +
                       $" and {rpIndicatorPerformanceIndicators} {typeof(RPIndicatorPerformance).Name } indicators" +
                       $" and {rpIndicatorExtendedIndicators} {typeof(RPIndicatorExtended).Name} indicators" +
                       $" ( duration {stopWatch.Elapsed} )");

            return esgResearchProfiles;
        }
    }
}
